﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Leadshine;
using MotionCS.Helper;

namespace MotionCS.Controller
{
    public class Smc300Api
    {
        public static Action<string> LogCallback;
        public static bool IsOpen { get; set; }
        private static ushort cardNo = 0;
        /// <summary>
        /// 控制卡初始化
        /// </summary>
        /// <returns></returns>
        public static bool BoardInit()
        {
            short nRet = LTSMC.smc_board_init(cardNo, 2, "192.168.5.11", 0);
            if(nRet == 0)
            {
                IsOpen = true;
                LogCallback?.Invoke("控制卡初始化成功.");
            }
            else
            {
                IsOpen = false;
            }

            ModifyVar("PcRun", new long[] { 1 }, 1);

            return IsOpen;
        }
        /// <summary>
        /// 控制卡关闭
        /// </summary>
        public static void BoardClose()
        {
            if (IsOpen)
            {
                ModifyVar("PcRun", new long[] { 0 }, 1);
                ThreadHelper.Delay(50);
                IsOpen = false;  
                short nRet = LTSMC.smc_board_close(cardNo);                
            }
        }
        /// <summary>
        /// 设置轴脉冲输出模式
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="outmode"></param>
        public static void SetPulseOutmode(int axis, int outmode)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_set_pulse_outmode(cardNo, (ushort)axis, (ushort)outmode);
                ResultCheck("smc_set_pulse_outmode", nRet);
            }
        }
        /// <summary>
        /// 读取轴脉冲输出模式
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="outmode"></param>
        public static void GetPulseOutmode(int axis, ref ushort outmode)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_get_pulse_outmode(cardNo, (ushort)axis, ref outmode);
                ResultCheck("smc_get_pulse_outmode", nRet);
            }
        }
        /// <summary>
        /// 设置轴脉冲当量
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="equiv"></param>
        public static void SetEquiv(int axis, double equiv)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_set_equiv(cardNo, (ushort)axis, equiv);
                ResultCheck("smc_set_equiv", nRet);
            }
        }
        /// <summary>
        /// 读取轴脉冲当量设置
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="equiv"></param>
        public static void GetEquiv(int axis, ref double equiv)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_get_equiv(cardNo, (ushort)axis, ref equiv);
                ResultCheck("smc_get_equiv", nRet);
            }
        }
        /// <summary>
        /// 设置软限位
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="enable"></param>
        /// <param name="sel"></param>
        /// <param name="action"></param>
        /// <param name="NLimit"></param>
        /// <param name="PLimit"></param>
        public static void SetSoftLimit(int axis, ushort enable, ushort sel, ushort action, double NLimit, double PLimit)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_set_softlimit_unit(cardNo, (ushort)axis, enable, sel, action, NLimit, PLimit);
                ResultCheck("smc_set_softlimit_unit", nRet);
            }
        }
        /// <summary>
        /// 读取软限位设置
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="enable"></param>
        /// <param name="sel"></param>
        /// <param name="action"></param>
        /// <param name="NLimit"></param>
        /// <param name="PLimit"></param>
        public static void GetSoftLimit(int axis, ref ushort enable, ref ushort sel, ref ushort action, ref double NLimit, ref double PLimit)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_get_softlimit_unit(cardNo, (ushort)axis, ref enable, ref sel, ref action, ref NLimit, ref PLimit);
                ResultCheck("smc_get_softlimit_unit", nRet);
            }
        }
        /// <summary>
        /// 设置单轴运动速度曲线
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="minVel"></param>
        /// <param name="maxVel"></param>
        /// <param name="tacc"></param>
        /// <param name="tdec"></param>
        /// <param name="stopVel"></param>
        public static void SetProfileUnit(int axis, double minVel, double maxVel, double tacc, double tdec, double stopVel)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_set_profile_unit(cardNo, (ushort)axis, minVel, maxVel, tacc, tdec, stopVel);
                ResultCheck("smc_set_profile_unit", nRet);
            }
        }
        /// <summary>
        /// 读取单轴运动速度曲线
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="minVel"></param>
        /// <param name="maxVel"></param>
        /// <param name="tacc"></param>
        /// <param name="tdec"></param>
        /// <param name="stopVel"></param>
        public static void GetProfileUnit(int axis, ref double minVel, ref double maxVel, ref double tacc, ref double tdec, ref double stopVel)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_get_profile_unit(cardNo, (ushort)axis, ref minVel, ref maxVel, ref tacc, ref tdec, ref stopVel);
                ResultCheck("smc_get_profile_unit", nRet);
            }
        }
        /// <summary>
        /// 设置单轴速度曲线S段参数值
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="s_mode"></param>
        /// <param name="s_para"></param>
        public static void SetSProfile(int axis, ushort s_mode, double s_para)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_set_s_profile(cardNo, (ushort)axis, s_mode, s_para);
                ResultCheck("smc_set_s_profile", nRet);
            }
        }
        /// <summary>
        /// 读取单轴速度曲线S段参数
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="s_mode"></param>
        /// <param name="s_para"></param>
        public static void GetSProfile(int axis, ushort s_mode, ref double s_para)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_get_s_profile(cardNo, (ushort)axis, s_mode, ref s_para);
                ResultCheck("smc_get_s_profile", nRet);
            }
        }
        /// <summary>
        /// 定长运动
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="dist"></param>
        /// <param name="mode"></param>
        public static void PmoveUnit(int axis,double dist, ushort mode)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_pmove_unit(cardNo, (ushort)axis, dist, mode);
                ResultCheck("smc_pmove_unit", nRet);
            }
        }
        /// <summary>
        /// 指定轴连续运动
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="dir"></param>
        public static void Vmove(int axis, ushort dir)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_vmove(cardNo, (ushort)axis, dir);
                ResultCheck("smc_vmove", nRet);
            }
        }
        /// <summary>
        /// 在线改变指定轴的当前目标位置
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="pos"></param>
        public static void ResetTargetPositionUnit(int axis, double pos)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_reset_target_position_unit(cardNo, (ushort)axis, pos);
                ResultCheck("smc_reset_target_position_unit", nRet);
            }
        }
        /// <summary>
        /// 强行改变指定轴的当前目标位置
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="pos"></param>
        public static void UpdateTargetPositionUnit(int axis, double pos)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_update_target_position_unit(cardNo, (ushort)axis, pos);
                ResultCheck("smc_update_target_position_unit", nRet);
            }
        }
        /// <summary>
        /// 在线改变指定轴的当前运动速度
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="vel"></param>
        /// <param name="taccdec"></param>
        public static void ChangeSpeedUnit(int axis, double vel, double taccdec)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_change_speed_unit(cardNo, (ushort)axis, vel, taccdec);
                ResultCheck("smc_change_speed_unit", nRet);
            }
        }
        /// <summary>
        /// 设置指定轴的当前指令位置计算值
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="pos"></param>
        public static void SetPositionUnit(int axis, double pos)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_set_position_unit(cardNo, (ushort)axis, pos);
                ResultCheck("smc_set_position_unit", nRet);
            }
        }
        /// <summary>
        /// 读取指定轴的当前指令位置计数器值
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="pos"></param>
        public static void GetPositionUnit(int axis, ref double pos)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_get_position_unit(cardNo, (ushort)axis, ref pos);
                ResultCheck("smc_get_position_unit", nRet);
            }
        }
        /// <summary>
        /// 读取指定轴的当前单轴速度
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="speed"></param>
        public static void ReadCurrentSpeedUnit(int axis, ref double speed)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_read_current_speed_unit(cardNo, (ushort)axis, ref speed);
                ResultCheck("smc_read_current_speed_unit", nRet);
            }
        }
        /// <summary>
        /// 检测指定轴的运动状态
        /// </summary>
        /// <param name="axis"></param>
        /// <return> 0 运行中 1 已停止 </return>
        public static short CheckDone(int axis)
        {
            return LTSMC.smc_check_done(cardNo, (ushort)axis);
        }
        /// <summary>
        /// 设置轴ORG原点信号
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="logic"></param>
        /// <param name="filter"></param>
        public static void SetHomePinLogic(int axis, ushort logic, double filter)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_set_home_pin_logic(cardNo, (ushort)axis, logic, filter);
                ResultCheck("smc_set_home_pin_logic", nRet);
            }
        }
        /// <summary>
        /// 读取轴ORG原点信号
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="logic"></param>
        /// <param name="filter"></param>
        public static void GetHomePinLogic(int axis, ref ushort logic, ref double filter)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_get_home_pin_logic(cardNo, (ushort)axis, ref logic, ref filter);
                ResultCheck("smc_get_home_pin_logic", nRet);
            }
        }
        /// <summary>
        /// 设置轴回原点模式
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="home_dir"></param>
        /// <param name="vel_mode"></param>
        /// <param name="mode"></param>
        /// <param name="ez_count"></param>
        public static void SetHomeMode(int axis, int home_dir, double vel_mode, int mode, ushort ez_count)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_set_homemode(cardNo, (ushort)axis, (ushort)home_dir, vel_mode, (ushort)mode, ez_count);
                ResultCheck("smc_set_homemode", nRet);
            }
        }
        /// <summary>
        /// 读取轴回原点模式
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="home_dir"></param>
        /// <param name="vel_mode"></param>
        /// <param name="mode"></param>
        /// <param name="ez_count"></param>
        public static void GetHomeMode(int axis, ref ushort home_dir, ref double vel_mode, ref ushort mode, ref ushort ez_count)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_get_homemode(cardNo, (ushort)axis, ref home_dir, ref vel_mode, ref mode, ref ez_count);
                ResultCheck("smc_get_homemode", nRet);
            }
        }
        /// <summary>
        /// 设置回零遇限位是否反找
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="enable"></param>
        //public static void SetHomeElReturn(int axis, ushort enable)
        //{
        //    if (IsOpen)
        //    {
        //        short nRet = LTSMC.smc_set_home_el_return(cardNo, (ushort)axis, enable);
        //        ResultCheck("smc_set_home_el_return", nRet);
        //    }
        //}
        /// <summary>
        /// 读取回零遇限位是否反找
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="enable"></param>
        //public static void GetHomeElReturn(int axis, ref ushort enable)
        //{
        //    if (IsOpen)
        //    {
        //        short nRet = LTSMC.smc_get_home_el_return(cardNo, (ushort)axis, ref enable);
        //        ResultCheck("smc_get_home_el_return", nRet);
        //    }
        //}
        /// <summary>
        /// 设置回零偏移量及清零模式
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="enable"></param>
        /// <param name="position"></param>
        public static void SetHomePositionUnit(int axis, ushort enable, double position)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_set_home_position_unit(cardNo, (ushort)axis, enable, position);
                ResultCheck("smc_set_home_position_unit", nRet);
            }
        }
        /// <summary>
        /// 读取回零偏移量及清零模式
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="enable"></param>
        /// <param name="position"></param>
        public static void GetHomePositionUnit(int axis, ref ushort enable, ref double position)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_get_home_position_unit(cardNo, (ushort)axis, ref enable, ref position);
                ResultCheck("smc_get_home_position_unit", nRet);
            }
        }
        /// <summary>
        /// 设置回零速度参数
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="low_vel"></param>
        /// <param name="high_vel"></param>
        /// <param name="tacc"></param>
        /// <param name="tdec"></param>
        public static void SetHomeProfileUnit(int axis, double low_vel, double high_vel, double tacc, double tdec)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_set_home_profile_unit(cardNo, (ushort)axis, low_vel, high_vel, tacc, tdec);
                ResultCheck("smc_set_home_profile_unit", nRet);
            }
        }
        /// <summary>
        /// 读取回零速度参数
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="enable"></param>
        /// <param name="deviation"></param>
        public static void GetHomeProfileUnit(int axis, ref double low_vel, ref double high_vel, ref double tacc, double tdec)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_get_home_profile_unit(cardNo, (ushort)axis, ref low_vel, ref high_vel, ref tacc, ref tdec);
                ResultCheck("smc_get_home_profile_unit", nRet);
            }
        }
        /// <summary>
        /// 回原点运动
        /// </summary>
        /// <param name="axis"></param>
        public static void HomeMove(int axis)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_home_move(cardNo, (ushort)axis);
                ResultCheck("smc_home_mvoe", nRet);
            }
        }
        /// <summary>
        /// 读取回零执行状态
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="state"></param>
        public static void GetHomeResult(int axis, ref ushort state)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_get_home_result(cardNo, (ushort)axis, ref state);
                ResultCheck("smc_get_home_result", nRet);
            }
        }
        /// <summary>
        /// 设置EL限位信号
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="el_enable"></param>
        /// <param name="el_logic"></param>
        /// <param name="el_mode"></param>
        public static void SetElMode(int axis, int el_enable, int el_logic, ushort el_mode)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_set_el_mode(cardNo, (ushort)axis, (ushort)el_enable, (ushort)el_logic, el_mode);
                ResultCheck("smc_set_el_mode", nRet);
            }
        }
        /// <summary>
        /// 获取EL限位信号
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="el_enable"></param>
        /// <param name="el_logic"></param>
        /// <param name="el_mode"></param>
        public static void GetElMode(int axis, ref ushort el_enable, ref ushort el_logic, ref ushort el_mode)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_get_el_mode(cardNo, (ushort)axis, ref el_enable, ref el_logic, ref el_mode);
                ResultCheck("smc_get_el_mode", nRet);
            }
        }

        /// <summary>
        /// 读取指定轴有关运动信号状态
        /// </summary>
        /// <param name="axis"></param>
        public static UInt32 AxisIoStatus(int axis)
        {
            return LTSMC.smc_axis_io_status(cardNo, (ushort)axis);
        }
        /// <summary>
        /// 指定轴停止运动
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="mode"></param>
        public static void AxisStop(int axis, ushort mode)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_stop(cardNo, (ushort)axis, mode);
                ResultCheck("smc_stop", nRet);
            }
        }
        /// <summary>
        /// 紧急停止所有轴
        /// </summary>
        public static void EmgStop()
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_emg_stop(cardNo);
                ResultCheck("smc_emg_stop", nRet);
            }
        }
        /// <summary>
        /// 读取正在运动的目标位置
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="pos"></param>
        //public static void GetTargetPosition(int axis, ref double pos)
        //{
        //    if (IsOpen)
        //    {
        //        short nRet = LTSMC.smc_get_target_position_unit(cardNo, (ushort)axis, ref pos);
        //        ResultCheck("smc_get_target_position_unit", nRet);
        //    }
        //}
        /// <summary>
        /// 读取指定轴的运动模式
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="mode"></param>
        public static void GetAxisRunMode(int axis, ref ushort mode)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_get_axis_run_mode(cardNo, (ushort)axis, ref mode);
                ResultCheck("smc_get_axis_run_mode", nRet);
            }
        }
        /// <summary>
        /// 读取指定轴的停止原因
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="stopReason"></param>
        public static void GetStopReason(int axis, ref Int32 stopReason)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_get_stop_reason(cardNo, (ushort)axis, ref stopReason);
                ResultCheck("smc_get_stop_reason", nRet);
            }
        }
        /// <summary>
        /// 清除指定轴的停止原因
        /// </summary>
        /// <param name="axis"></param>
        public static void ClearStopReason(int axis)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_clear_stop_reason(cardNo, (ushort)axis);
                ResultCheck("smc_clear_stop_reason", nRet);
            }
        }
        /// <summary>
        /// 读取指定控制卡的某个输入端口的电平
        /// </summary>
        /// <param name="bitno"></param>
        /// <returns></returns>
        public static short ReadInbit(ushort bitno)
        {
            if (IsOpen)
            {
                return LTSMC.smc_read_inbit(cardNo, bitno);
            }
            return 0;
        }
        /// <summary>
        /// 设置指定控制卡的某个输出端口的电平
        /// </summary>
        /// <param name="bitno"></param>
        /// <param name="onoff"></param>
        public static void WriteOutbit(ushort bitno, ushort onoff)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_write_outbit(cardNo, bitno, onoff);
                ResultCheck("smc_write_outbit", nRet);
            }
        }
        /// <summary>
        /// 读取指定控制卡的某个输出端口的电平
        /// </summary>
        /// <param name="bitno"></param>
        /// <returns></returns>
        public static short ReadOutbit(ushort bitno)
        {
            if (IsOpen)
            {
                return LTSMC.smc_read_outbit(cardNo, bitno);
            }
            return 0;
        }
        /// <summary>
        /// 读取指定控制卡的全部输入端口的电平
        /// </summary>
        /// <param name="portno"></param>
        /// <returns></returns>
        public static UInt32 ReadInport(ushort portno)
        {
            if (IsOpen)
            {
                return LTSMC.smc_read_inport(cardNo, portno);
            }

            return 0;
        }
        /// <summary>
        /// 读取指定控制卡的全部输出口的电平
        /// </summary>
        /// <param name="portno"></param>
        /// <returns></returns>
        public static UInt32 ReadOutport(ushort portno)
        {
            if (IsOpen)
            {
                return LTSMC.smc_read_outport(cardNo, portno);
            }
            return 0;
        }
        /// <summary>
        /// 设置指定控制卡端口的电平
        /// </summary>
        /// <param name="bitno"></param>
        /// <param name="onoff"></param>
        public static void WriteOutport(ushort portno, uint val)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_write_outport(cardNo, portno, val);
                ResultCheck("smc_write_outport", nRet);
            }
        }
        /// <summary>
        /// 设置轴IO映射关系
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="type"></param>
        /// <param name="mapType"></param>
        /// <param name="mapIo"></param>
        /// <param name="time"></param>
        public static void SetAxisIoMap(int axis, ushort type, ushort mapType, int mapIo, double time)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_set_axis_io_map(cardNo, (ushort)axis, type, mapType, (ushort)mapIo, time);
                ResultCheck("smc_set_axis_io_map", nRet);
            }
        }
        /// <summary>
        /// 读取轴IO映射关系
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="type"></param>
        /// <param name="mapType"></param>
        /// <param name="mapIo"></param>
        /// <param name="time"></param>
        public static void GetAxisIoMap(int axis, ushort type, ushort mapType, ushort mapIo, double time)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_get_axis_io_map(cardNo, (ushort)axis, type, ref mapType, ref mapIo, ref time);
                ResultCheck("smc_get_axis_io_map", nRet);
            }
        }
        /// <summary>
        /// 统一设置所有专用IO的滤波时间
        /// </summary>
        /// <param name="filter_time"></param>
        //public static void SetSpecialInputFilter(double filter_time)
        //{
        //    if (IsOpen)
        //    {
        //        short nRet = LTSMC.smc_set_special_input_filter(cardNo, filter_time);
        //        ResultCheck("smc_set_special_input_filter", nRet);
        //    }
        //}
        /// <summary>
        /// 控制轴的伺服使能端口的输出
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="on_off"></param>
        public static void WriteSevonPin(int axis, ushort on_off)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_write_sevon_pin(cardNo, (ushort)axis, on_off);
                ResultCheck("smc_write_sevon_pin", nRet);
            }
        }
        /// <summary>
        /// 读取轴的伺服使能的电平
        /// </summary>
        /// <param name="axis"></param>
        public static short ReadSevonPin(int axis)
        {
            if (IsOpen)
            {
                return LTSMC.smc_read_sevon_pin(cardNo, (ushort)axis);
            }
            else
            {
                return 0;
            }
        }
        /// <summary>
        /// 读取轴的RDY端口的电平
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="on_off"></param>
        public static short ReadRdyPin(int axis)
        {
            if (IsOpen)
            {
                return LTSMC.smc_read_rdy_pin(cardNo, (ushort)axis);
            }
            else
            {
                return 0;
            }
        }
        /// <summary>
        /// 设置轴的INP信号设置
        /// </summary>
        /// <param name="axis"></param>
        public static void SetInpMode(int axis, int enable, int inp_logic)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_set_inp_mode(cardNo, (ushort)axis, (ushort)enable, (ushort)inp_logic);
                ResultCheck("smc_set_inp_mode", nRet);
            }
        }
        /// <summary>
        /// 读取轴的INP信号设置
        /// </summary>
        /// <param name="axis"></param>
        public static void GetInpMode(int axis, ref ushort enable, ref ushort inp_logic)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_get_inp_mode(cardNo, (ushort)axis, ref enable, ref inp_logic);
                ResultCheck("smc_get_inp_mode", nRet);
            }
        }
        /// <summary>
        /// 设置轴的Alm信号设置
        /// </summary>
        /// <param name="axis"></param>
        public static void SetAlmMode(int axis, int enable, int alm_logic, ushort alm_action)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_set_alm_mode(cardNo, (ushort)axis, (ushort)enable, (ushort)alm_logic, alm_action);
                ResultCheck("smc_set_alm_mode", nRet);
            }
        }
        /// <summary>
        /// 读取轴的Alm信号设置
        /// </summary>
        /// <param name="axis"></param>
        public static void GetAlmMode(int axis, ref ushort enable, ref ushort alm_logic, ref ushort alm_action)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_get_alm_mode(cardNo, (ushort)axis, ref enable, ref alm_logic, ref alm_action);
                ResultCheck("smc_get_alm_mode", nRet);
            }
        }
        /// <summary>
        /// 设置轴的ERC信号输出
        /// </summary>
        /// <param name="axis"></param>
        public static void WriteErcPin(int axis, ushort sel)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_write_erc_pin(cardNo, (ushort)axis, sel);
                ResultCheck("smc_write_erc_pin", nRet);
            }
        }
        /// <summary>
        /// 读取轴的ERC端口电平
        /// </summary>
        /// <param name="axis"></param>
        public static short ReadErcPin(int axis)
        {
            if (IsOpen)
            {
                return LTSMC.smc_read_erc_pin(cardNo, (ushort)axis);
            }
            else
            {
                return 0;
            }
        }
        /// <summary>
        /// 设置编码器的计数方式
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="mode"></param>
        public static void SetCounterInmode(int axis, int mode)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_set_counter_inmode(cardNo, (ushort)axis, (ushort)mode);
                ResultCheck("smc_set_counter_inmode", nRet);
            }
        }
        /// <summary>
        /// 读取编码器的计数方式
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="mode"></param>
        public static void GetCounterInmode(int axis, ref ushort mode)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_get_counter_inmode(cardNo, (ushort)axis, ref mode);
                ResultCheck("smc_get_counter_inmode", nRet);
            }
        }
        /// <summary>
        /// 设置编码器方向
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="dir"></param>
        //public static void SetEncoderDir(int axis, ushort dir)
        //{
        //    if (IsOpen)
        //    {
        //        short nRet = LTSMC.smc_set_encoder_dir(cardNo, (ushort)axis, dir);
        //        ResultCheck("smc_set_encoder_dir", nRet);
        //    }
        //}
        /// <summary>
        /// 设置编码器脉冲计数值
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="encode_val"></param>
        public static void SetEncoder(int axis, int encode_val)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_set_encoder(cardNo, (ushort)axis, encode_val);
                ResultCheck("smc_set_encoder", nRet);
            }
        }
        /// <summary>
        /// 读取编码器脉冲计数值
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="encode_val"></param>
        public static int GetEncoder(int axis)
        {
            if (IsOpen)
            {
                return LTSMC.smc_get_encoder(cardNo, (ushort)axis);
            }
            else
            {
                return 0;
            }
        }
        /// <summary>
        /// 设置指定轴的EZ信号
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="ez_logic"></param>
        /// <param name="ez_mode"></param>
        /// <param name="filter"></param>
        public static void SetEzMode(int axis, ushort ez_logic, ushort ez_mode, double filter)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_set_ez_mode(cardNo, (ushort)axis, ez_logic, ez_mode, filter);
                ResultCheck("smc_set_ez_mode", nRet);
            }
        }
        /// <summary>
        /// 读取指定轴的EZ信号设置
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="ez_logic"></param>
        /// <param name="ez_mode"></param>
        /// <param name="filter"></param>
        public static void GetEzMode(int axis, ref ushort ez_logic, ref ushort ez_mode, ref double filter)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_get_ez_mode(cardNo, (ushort)axis, ref ez_logic, ref ez_mode, ref filter);
                ResultCheck("smc_get_ez_mode", nRet);
            }
        }
        /// <summary>
        /// 设置指定轴的当前编码器计数值
        /// </summary>
        /// <param name="bitno"></param>
        /// <param name="pos"></param>
        public static void SetEncoderUnit(int axis, double pos)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_set_encoder_unit(cardNo, (ushort)axis, pos);
                ResultCheck("smc_set_encoder_unit", nRet);
            }
        }
        /// <summary>
        /// 读取指定轴的当前编码器计数值
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="pos"></param>
        public static void GetEncoderUnit(int axis, ref double pos)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_get_encoder_unit(cardNo, (ushort)axis, ref pos);
                ResultCheck("smc_get_encoder_unit", nRet);
            }
        }
        /// <summary>
        /// 设置EMG急停信号
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="enable"></param>
        /// <param name="logic"></param>
        public static void SetEmgMode(int axis, int enable, int logic)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_set_emg_mode(cardNo, (ushort)axis, (ushort)enable, (ushort)logic);
                ResultCheck("smc_set_emg_mode", nRet);
            }
        }
        /// <summary>
        /// 读取EMG急停信号
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="enable"></param>
        /// <param name="logic"></param>
        public static void GetEmgMode(int axis, ref ushort enable, ref ushort logic)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_get_emg_mode(cardNo, (ushort)axis, ref enable, ref logic);
                ResultCheck("smc_get_emg_mode", nRet);
            }
        }
        /// <summary>
        /// 设置减速停止信号
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="enable"></param>
        /// <param name="logic"></param>
        public static void SetIoDstpMode(int axis, ushort enable, ushort logic)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_set_io_dstp_mode(cardNo, (ushort)axis, enable, logic);
                ResultCheck("smc_set_io_dstp_mode", nRet);
            }
        }
        /// <summary>
        /// 读取减速停止信号设置
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="enable"></param>
        /// <param name="logic"></param>
        public static void GetIoDstpMode(int axis, ref ushort enable, ref ushort logic)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_get_io_dstp_mode(cardNo, (ushort)axis, ref enable, ref logic);
                ResultCheck("smc_get_io_dstp_mode", nRet);
            }
        }
        /// <summary>
        /// 设置减速停止时间
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="time"></param>
        public static void SetDecStopTime(int axis, double time)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_set_dec_stop_time(cardNo, (ushort)axis, time);
                ResultCheck("smc_set_stop_time", nRet);
            }
        }
        /// <summary>
        /// 读取减速停止时间
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="time"></param>
        public static void GetDecStopTime(int axis, ref double time)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_get_dec_stop_time(cardNo, (ushort)axis, ref time);
                ResultCheck("smc_get_stop_time", nRet);
            }
        }
        /// <summary>
        /// 设置高速比较模式
        /// </summary>
        /// <param name="hcmp"></param>
        /// <param name="cmp_mode"></param>
        public static void HcmpSetMode(ushort hcmp, ushort cmp_mode)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_hcmp_set_mode(cardNo, hcmp, cmp_mode);
                ResultCheck("smc_hcmp_set_mode", nRet);
            }
        }
        /// <summary>
        /// 获取高速比较模式
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="time"></param>
        public static void HcmpGetMode(ushort hcmp, ref ushort cmp_mode)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_hcmp_get_mode(cardNo, hcmp, ref cmp_mode);
                ResultCheck("smc_hcmp_get_mode", nRet);
            }
        }

        /// <summary>
        /// 设置高速比较器
        /// </summary>
        /// <param name="hcmp"></param>
        /// <param name="cmp_mode"></param>
        public static void HcmpSetConfig(ushort hcmp, int axis, ushort cmp_source, ushort cmp_logic, int time)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_hcmp_set_config(cardNo, hcmp, (ushort)axis, cmp_source, cmp_logic, time);
                ResultCheck("smc_hcmp_set_config", nRet);
            }
        }
        /// <summary>
        /// 获取高速比较器
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="time"></param>
        public static void HcmpGetConfig(ushort hcmp, ref ushort axis, ref ushort cmp_source, ref ushort cmp_logic, ref int time)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_hcmp_get_config(cardNo, hcmp, ref axis, ref cmp_source, ref cmp_logic, ref time);
                ResultCheck("smc_hcmp_get_config", nRet);
            }
        }
        /// <summary>
        /// 添加/更新高速比较点
        /// </summary>
        /// <param name="hcmp"></param>
        /// <param name="cmp_pos"></param>
        public static void HcmpAddPointUnit(ushort hcmp, double cmp_pos)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_hcmp_add_point_unit(cardNo, hcmp, cmp_pos);
                ResultCheck("smc_hcmp_add_point_unit", nRet);
            }
        }
        /// <summary>
        /// 设置高速比较线性模式参数
        /// </summary>
        /// <param name="hcmp"></param>
        /// <param name="Increment"></param>
        /// <param name="Count"></param>
        public static void HcmpSetLinerUnit(ushort hcmp, double Increment, int Count)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_hcmp_set_liner_unit(cardNo, hcmp, Increment, Count);
                ResultCheck("smc_hcmp_set_liner_unit", nRet);
            }
        }
        /// <summary>
        /// 获取高速比较线性模式参数
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="time"></param>
        public static void HcmpGetLinerUnit(ushort hcmp, ref double Increment, ref int Count)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_hcmp_get_liner_unit(cardNo, hcmp, ref Increment, ref Count);
                ResultCheck("smc_hcmp_get_liner_unit", nRet);
            }
        }
        /// <summary>
        /// 读取高速比较状态
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="time"></param>
        public static void HcmpGetCurrentStateUnit(ushort hcmp, ref int remained_points, ref double current_point, ref int runned_points)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_hcmp_get_current_state_unit(cardNo, hcmp, ref remained_points, ref current_point, ref runned_points);
                ResultCheck("smc_hcmp_get_current_state_unit", nRet);
            }
        }
        /// <summary>
        /// 清除已添加的所有高速位置比较点
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="time"></param>
        public static void HcmpClearPoint(ushort hcmp)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_hcmp_clear_points(cardNo, hcmp);
                ResultCheck("smc_hcmp_clear_points", nRet);
            }
        }
        /// <summary>
        /// 读取指定 CMP 端口的电平
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="time"></param>
        public static void ReadCmpPin(ushort hcmp)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_read_cmp_pin(cardNo, hcmp);
                ResultCheck("smc_read_cmp_pin", nRet);
            }
        }
        /// <summary>
        /// 控制指定 CMP 端口的输出
        /// </summary>
        /// <param name="hcmp"></param>
        /// <param name="on_off"></param>
        public static void HcmpWriteCmpPin(ushort hcmp, ushort on_off)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.smc_write_cmp_pin(cardNo, hcmp, on_off);
                ResultCheck("smc_write_cmp_pin", nRet);
            }
        }
        /// <summary>
        /// 设置扩展模块的输出端口电平
        /// </summary>
        /// <param name="noteid"></param>
        /// <param name="bit"></param>
        /// <param name="value"></param>
        public static void NmcsReadInbit(ushort port, ushort noteid, ushort bit, ushort value)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.nmcs_write_outbit(cardNo, port, noteid, bit, value);
                ResultCheck("nmcs_write_outbit", nRet);
            }
        }
        /// <summary>
        /// 设置扩展模块的输出端口电平
        /// </summary>
        /// <param name="noteid"></param>
        /// <param name="bit"></param>
        /// <param name="value"></param>
        public static void NmcsWriteOutbit(ushort port, ushort noteid, ushort bit, ushort value)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.nmcs_write_outbit(cardNo, port, noteid, bit, value);
                ResultCheck("nmcs_write_outbit", nRet);
            }
        }
        /// <summary>
        /// 读取扩展模块的输出端口电平
        /// </summary>
        /// <param name="noteid"></param>
        /// <param name="bit"></param>
        /// <param name="value"></param>
        public static void NmcsReadOutbit(ushort port, ushort noteid, ushort bit, ref ushort value)
        {
            if (IsOpen)
            {
                short nRet = LTSMC.nmcs_read_outbit(cardNo, port, noteid, bit, ref value);
                ResultCheck("nmcs_read_outbit", nRet);
            }
        }

        public static int PersistentRegSetByte(ushort start, ushort inum, byte[] pdata)
        {
            if (IsOpen)
            {
                int ret = LTSMC.smc_set_persistent_reg(cardNo, start, inum, pdata);
                ResultCheck("smc_set_persistent_reg", ret);
                return ret;
            }
            else
            {
                return 1;
            }
        }

        public static int PersistentRegGetByte(ushort start, ushort inum, byte[] pdata)
        {
            if (IsOpen)
            {
                int ret = LTSMC.smc_get_persistent_reg(cardNo, start, inum, pdata);
                ResultCheck("smc_get_persistent_reg", ret);
                return ret;
            }
            else
            {
                return 1;
            }
        }

        public static int PersistentRegSetfloat(ushort start, float[] pdata)
        {
            if (IsOpen)
            {

                for (int i = 0; i < pdata.Length; i++)
                {
                    byte[] dat = BitConverter.GetBytes(pdata[i]);
                    ushort idx = (ushort)(start + (i * 4));
                    int ret = PersistentRegSetByte(idx, 4, dat);
                    if (ret != 0)
                    {
                        return ret;
                    }
                }
                return 0;
            }
            else
            {
                return 1;
            }
        }

        public static int PersistentRegGetfloat(ushort start, float[] pdata)
        {
            if (IsOpen)
            {
                byte[] dat = new byte[4];
                for (int i = 0; i < pdata.Length; i++)
                {
                    ushort idx = (ushort)(start + (i * 4));
                    int ret = PersistentRegGetByte(idx, 4, dat);
                    if (ret != 0)
                    {
                        return ret;
                    }
                    pdata[i] = BitConverter.ToSingle(dat, 0);
                }
                return 0;
            }
            else
            {
                return 1;
            }
        }

        private static void ModifyVar(string varstr, long[] var, int varnum)
        {
            if (IsOpen)
            {
                int ret = LTSMC.smc_modify_var(cardNo, varstr, var, varnum);
                ResultCheck("smc_modify_var", ret);
            }
        }

        /// <summary>
        /// 返回值校验
        /// </summary>
        /// <param name="command"></param>
        /// <param name="nRet"></param>
        private static void ResultCheck(string command, Int32 nRet)
        {
            if (nRet == 0)
            {
                return;
            }

            if (nRet == 1 || nRet == 3)
            {
                IsOpen = false;
            }

            switch (nRet)
            {
                case 104:
                    LogCallback?.Invoke("轴处于正限位,不能正向运动.");
                    break;
                case 105:
                    LogCallback?.Invoke("轴处于负限位,不能负向运动.");
                    break;
                case 106:
                    LogCallback?.Invoke("轴处于软正限位,不能正向运动.");
                    break;
                case 107:
                    LogCallback?.Invoke("轴处于软负限位,不能负向运动.");
                    break;
            }

            LogCallback?.Invoke(command + ", ResultCode:" + nRet.ToString());
        }
    }
}
